package br.com.rapidrest.chain;

import java.io.PrintWriter;
import java.lang.reflect.Method;

import javax.servlet.http.HttpServletResponse;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;

import br.com.rapidrest.exception.ChainException;

public class VelocityResponseCommand implements Command {

	private String contentType = "text/html; charset=UTF-8";

	private String extension = ".velocity";

	private VelocityEngine velocityEngine;

	public VelocityResponseCommand(VelocityEngine velocityEngine) {
		super();
		this.velocityEngine = velocityEngine;
	}

	@Override
	public void execute(Chain chain) throws ChainException {
		BasicChainContext context = (BasicChainContext) chain.getContext();

		try {
			Class<?> beanClass = context.getBean().getClass();
			Object returnedValue = context.getReturnedValue();

			String packagePath = beanClass.getPackage().getName().replace(".",
					"/");
			String className = beanClass.getSimpleName();

			Method method = context.getMethod();

			StringBuilder templateName = new StringBuilder();
			templateName.append(packagePath).append("/").append(className);
			if (method != null
					&& !method.getName()
							.equals(BeanCommand.DEFAULT_INIT_METHOD)) {
				templateName.append(".").append(method.getName());
			}
			templateName.append(extension);

			Template template = velocityEngine.getTemplate(templateName
					.toString());
			VelocityContext velocityContext = new VelocityContext();
			velocityContext.put("page", context.getBean());
			if (returnedValue != null) {
				velocityContext.put("value", returnedValue);
			}

			HttpServletResponse response = context.getResponse();
			response.setContentType(contentType);
			PrintWriter writer = response.getWriter();
			template.merge(velocityContext, writer);
		} catch (Exception e) {
			throw new ChainException(e);
		}
	}

	public String getContentType() {
		return contentType;
	}

	public void setContentType(String contentType) {
		this.contentType = contentType;
	}

	public String getExtension() {
		return extension;
	}

	public void setExtension(String extension) {
		this.extension = extension;
	}

}